# -*- coding: utf-8 -*-

import gevent
from gevent import socket
from gevent.server import StreamServer as Acceptor

import json

p_load = json.loads
p_dump = json.dumps

class Connection (object):

    DELIMITER = "\xff\x00\xff"

    def __init__ (self, socket, address):
        self.id = address
        self.socket = socket
        self.lost = False
        self.messages = []

    def start (self):
        gevent.spawn (self.handle)

    def handle (self):
        received_data = ""
        while True:
            try:
                data = self.socket.recv (1024)
            except Exception as e:
                # connection lost
                break
            if not data:
                break
            received_data += data
            batches = received_data.split (Connection.DELIMITER)
            received_data = batches.pop () # last
            for batch in batches:
                self.messages.append (p_load (batch))
        self.lost = True
        self.socket.close ()

    def send (self, message):
        if not self.lost:
            data = p_dump (message) + Connection.DELIMITER
            self.socket.send (data)

    def close (self):
        self.socket.shutdown (socket.SHUT_RDWR)

    def __str__ (self):
        return "{Connection id:%s}" % str(self.id)

class Connector (object):

    def __init__ (self):
        self.status = "idle"
        self.address = None #address
        self.socket = None
        self.started = False

    def _start (self):
        if self.started: return
        try:
            self.status = "establishment..."
            self.started = True
            self.socket = socket.socket ()
            self.socket.settimeout (5.0)
            self.socket.connect (self.address)
            self.socket.settimeout (None)
            self.status = "done."
        #except socket.timeout as err:
        #    self.status = "EEE %s" % err
        except socket.error as err:
            self.status = "EEE %s" % str (err)
            self.socket = None
        self.started = False

    def start (self, address):
        if not self.started and self.socket is None:
            self.address = address
            gevent.spawn (self._start)

    def stop (self):
        if self.socket:
            pass
            #self.socket.shutdown (socket.SHUT_RDWR)
            #self.status = "idle"
        #self.socket = None

    def get_connection (self):
        if not self.started and self.socket:
            conn = Connection (self.socket, self.address)
            self.socket = None
            self.status = "idle"
            return conn
        return None

